import com.troyworks.datastructures.skiplist.simple.SkipListElement;
// implement a node in the skip list
class com.troyworks.datastructures.skiplist.SkipNode {
   // private int        nodeHeight;
    private var        nodeHeight:Number;
    
//    private int        key;
    private var        key:Number;
//    private com.troyworks.datastructures.skiplist.SkipNode[] fwdNodes;
    private var fwdNodes:Array;
    
//    private boolean[]  visited;
    private var  visited:Array;
    
    public static var MaxNodeValue:Number = 65536;
    public static var MinNodeValue:Number = 0;
    
      //  friend class SkipList;
    public function SkipNode(){
    	//route based on number of arguments
		if(arguments.length == 1){
			 this.initWithNumberOfNodes.apply(this, arguments);	
		}else if (arguments.length == 2){
			 this.initWithProbability.apply(this, arguments);	
		}
    }
    public function set2SkipNode(k:Number, h:Number) :Void{
        nodeHeight = h;
        key        = k;
        fwdNodes   = new Array(h+1);
        visited    = new Array(h+1);
        for (var x:Number = 1; x <= nodeHeight; x++) {
          fwdNodes[x] = null;
          visited[x]  = false;
        }
    }
        
    public function setSkipNode(h:Number):Void {
        nodeHeight = h;
        key        = MinNodeValue - 1; // -1 means not populated
        fwdNodes   = new Array(h+1);
        visited    = new Array(h+1);
        for (var x:Number = 1; x <= nodeHeight; x++) {
          fwdNodes[x] = null;
          visited[x]  = false;
        }
    }    
	public function initWithProbability( fProbability:Number, intMaxLevel:Number):Void
	{
	//	trace("init with probability");
	   this.myProbability = fProbability;
	   this.myMaxLevel = intMaxLevel;
	   this.myLevel = 0;  // level of empty list
	
	   // generate the header of the list:
	   this.myHeader = new SkipListElement(this.myMaxLevel, 0, null);
	
	   // append "NIL" element to header:
	   var nilElement:SkipListElement =	new SkipListElement(this.myMaxLevel, NIL_KEY, null);
	   for (var i:Number=0; i<=myMaxLevel; i++) {
		  this.myHeader.forward[i] = nilElement;
	   }
	}
	//The constructor presented makes it necessary to know the exact influence of the two parameters, probability and maximum level. If we choose the wrong parameters, we might construct a badly performing skip list. Since we cannot expect every programmer to know detailed skip-list parameters, we provide a second, easier-to-use constructor that does the job in most cases by calling the first constructor with good arguments. The only thing a programmer has to know at construction time is the estimated number of nodes:

    // 0.25 is a good probability finalstatic
    public static var GOOD_PROB:Number = 0.25;

	private var myProbability : Number;

	private var myMaxLevel : Number;

	private var myLevel : Number;

	private var myHeader : SkipListElement;

	private var NIL_KEY : Number;

	private var SkipList : Object;

	public function initWithNumberOfNodes(lngMaxNodes:Number):Void {
		//trace("init with number of nodes");
		 // see Pugh for math. background
		 this.initWithProbability(GOOD_PROB, Math.round(Math.ceil( Math.log(lngMaxNodes)/ Math.log(1/SkipNode.GOOD_PROB))-1));
	}
	/////////////////////////////////////////////
    public function getKey():Number {
        return key;
    }
    
    public function getHgt():Number {
        return nodeHeight;
    }
    
    public function setFwdNode(i:Number, x:SkipNode):Void {
        fwdNodes[i] = x;
    }
    
    public function getFwdNode(i:Number):SkipNode {
        return SkipNode(fwdNodes[i]);
    }
    
    public function setVisited(i:Number, b:Boolean):Void {
        visited[i] = b;
    }
    
    public function  getVisited(i:Number) :Boolean{
        return visited[i];
    }
    
    public function clearVisited():Void {
        for(var  i:Number=0;i<nodeHeight+1;i++) {
            visited[i] = false;
        }
    }
}
